﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using CRL.Core;
using System.Reflection;
using CRL;
using System.Collections.Concurrent;

namespace CRL.LambdaQuery
{
    public partial class ExpressionVisitor
    {
        public CRLExpression.CRLExpression MemberExpressionHandler(Expression exp, ExpressionType? nodeType = null, bool firstLevel = false)
        {
            #region MemberExpression
            //区分 属性表达带替换符{0} 变量值不带
            MemberExpression mExp = (MemberExpression)exp;
            var typeParameterName = (mExp.Expression as ParameterExpression)?.Name;
            if (mExp.Expression != null && mExp.Expression.NodeType == ExpressionType.Parameter) //like b.Name==b.Name1 或b.Name
            {
                #region MemberParameter
                var memberName = mExp.Member.Name;
                var type = mExp.Expression.Type;
                if (Base.CheckIfAnonymousType(mExp.Member.ReflectedType))//按匿名类
                {
                    var exp2 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = memberName, MemberType = type, typeParameterName = typeParameterName };
                    return exp2;
                }
                if (firstLevel)//没有运算符的BOOL判断
                {
                    var exp2 = exp.Equal(Expression.Constant(true));
                    return RouteExpressionHandler(exp2);
                }
                Attribute.FieldInnerAttribute field;
                var a = TypeCache.GetProperties(type, true).TryGetValue(memberName, out field);
                if (!a)
                {
                    throw new Exception("类型 " + type.Name + "." + memberName + " 未设置Mapping,请检查查询条件");
                }
                //if (field.DefaultCRLExpression != null)
                //{
                //    var c2 = field.DefaultCRLExpression;
                //    c2.Data = __DBAdapter.FieldNameFormat(field);
                //    return c2;
                //}
                var fieldStr = __DBAdapter.FieldNameFormat(field);
                var typeParameter = mExp.Expression as ParameterExpression;
                var exp3 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Name, Data = fieldStr, Data_ = field.MapingName, MemberType = type, typeParameterName = typeParameter.Name };
                //field.DefaultCRLExpression = exp3;
                return exp3;
                #endregion
            }
            else
            {
                #region 按值
                bool isConstant;
                var obj = GetParameExpressionValue(mExp, out isConstant);
                if (obj is Enum)
                {
                    obj = (int)obj;
                }
                else if (obj is Boolean)//sql2000需要转换
                {
                    obj = Convert.ToInt32(obj);
                }
                var exp4 = new CRLExpression.CRLExpression() { Type = CRLExpression.CRLExpressionType.Value, Data = obj, IsConstantValue = isConstant };
                //if (isConstant)
                //{
                //    MemberExpressionCache[key] = exp4;
                //}
                return exp4;
                #endregion
            }
            #endregion
        }
    }
}
